// 订阅器模式
let Dep = {
    clientList: {}, //订阅者集合
    // 添加订阅
    listen: function (key, fn) { //key：唯一id，fn:回调函数，可能有多个
        // 如果该项没有订阅，设置初始存储集合,然后添加回调函数
        (this.clientList[key] || (this.clientList[key] = [])).push(fn)
    },
    // 推送方法
    trigger: function () {
        // 这里的arguments指的下面的set方法传过来的[tag, val]，数组格式
        // key对应的就是tag，即唯一id
        let key = Array.prototype.shift.call(arguments)
        // 拿到当前的函数，为什么能拿到，是因为初始化时执行Dep.listen已经存储到clientList了
        // fns其实就是里面的回调函数
        let fns = this.clientList[key]
        if (!fns || fns.length === 0) {
            return false
        }
        // 执行节点对应的函数，即初始化挂载的回调
        for (let i = 0, fn; i < fns.length; i++) {
            fn = fns[i]
            fn.call(this, ...arguments)
        }
    }
}

// 数据劫持
let dataHijack = function ({ data, tag, datakey, selector }) {
    let value = ''
    // 对对象的各个属性进行劫持
    Object.defineProperty(data, datakey, {
        get: function () {
            console.log('取值')
            return value
        },
        set: function (val) {
            // 修改dataObj后会进入这里
            console.log('设置值')
            value = val
            // 数据变化
            Dep.trigger(tag, val)
        }
    })
    // 添加订阅者，这里指的是将订阅者1，2分别添加到clientList中，
    // 此时clientList的格式为：{view-1: [ƒ],view-2: [ƒ]}，f是这里传过去的函数
    Dep.listen(tag, function (text) {
        document.querySelector(selector).innerHTML = text
    })
}